<!DOCTYPE html>
<html>
<head>
<title>Using PubNub For Publish And Subscribe Communication</title>
 
<!-- Mobile viewport configuration. -->
<meta name="viewport" content = "width=device-width, user-scalable=no" />
 
<!-- Chat styles. -->
<link rel="stylesheet" type="text/css" href="../style.css" />
 
<!-- jQuery. -->
<script type="text/javascript" src="../../js/jquery-1.8.0.min.js"></script>
</head>
<body>
 
 
<!-- This is simple CHAT - what can I say, it's realtime. -->
 
<div class="messageLog">
<ul>
<!-- This will be populated dynamically. -->
</ul>
</div>
 
<form>
 
<input type="text" name="message"  />
 
<button type="submit" >Send</button>
 
</form>
 
 
<!-- --------------------------------------------------- -->
<!-- --------------------------------------------------- -->
<!-- --------------------------------------------------- -->
<!-- --------------------------------------------------- -->
 
 
<!-- PubNub configuration details. -->
<div
id="pubnub"
pub-key="pub-7b6592f6-4ddb-4af6-b1b3-0e74cefe818d"
sub-key="sub-f4baaac5-87e0-11e0-b5b4-1fcb5dd0ecb4"
origin="pubsub.pubnub.com"
ssl="off">
</div>
 
<!--
Include PubNub from THEIR content delivery netrwork. In the
documentation, they recommend this as the only way to build
things appropriately; it allows them to continually update
the security features.
 
NOTE: The PubNub script MUST BE included AFTER the above DIV
tag that provides the configuration keys.
-->
<script type="text/javascript" src="http://cdn.pubnub.com/pubnub-3.1.min.js"></script>
 
<script type="text/javascript">
 
// This is the user object. Each user has a unique ID that
// allows it to be differentiated from all other clients on
// the same subscribed channel.
var user = {
uuid: null,
subscribed: false
};
 
 
// Cache frequent DOM references.
dom = {};
dom.messageLog = $( "div.messageLog" );
dom.messageLogItems = dom.messageLog.find( "> ul" );
dom.form = $( "form" );
dom.formInput = dom.form.find( "input" );
dom.formSubmit = dom.form.find( "button" );
 
 
// Override form submit to PUSH message.
dom.form.submit(
function( event ){
 
// Cancel the default event.
event.preventDefault();
 
// Make sure there is a message to send and that the
// user is subscribed.
if (
!user.subscribed ||
!dom.formInput.val().length
){
 
// Nothing more we can do with this request.
return;
 
}
 
// Send the message to the current channel.
sendMessage( dom.formInput.val() );
 
// Clear and focus the current message so the
// user can keep typing new messages.
dom.formInput
.val( "" )
.focus()
;
 
}
);
 
 
// I append the given message to the message log.
function appendMessage( message, isFromMe ){
 
// Creat the message item.
var messageItem = $( "<li />" ).text( message );
 
// If the message is form me (ie. the local user) then
// add the appopriate class for visual distinction.
if (isFromMe){
 
messageItem.addClass( "mine" );
 
}
 
// Add the message element to the list.
dom.messageLogItems.append( messageItem );
 
}
 
 
// I send the given message to all subscribed clients.
function sendMessage( message ){
 
// Immediately add the message to the UI so the user
// feels like the interface is super responsive.
appendMessage( message, true );
 
// Push the message to PubNub. Attach the user UUID as
// part of the message so we can filter it out when it
// gets echoed back (as part of our subscription).
PUBNUB.publish({
channel: "hello_world",
message: {
uuid: user.uuid,
message: message
}
});
 
};
 
 
// I receive the message on the current channel.
function receiveMessage( message ){
 
// Check to make sure the message is not just being
// echoed back.
if (message.uuid === user.uuid){
 
// This message has already been handled locally.
return;
 
}
 
// Add the message to the chat log.
appendMessage( message.message );
 
}
 
 
// -------------------------------------------------- //
// -------------------------------------------------- //
 
 
// In order to initialize the system, we have to wait for the
// client to receive a UUID and for the subscription to the
// PubNub server to be established.
var init = $.when(
 
// Get the user ID.
getUUID(),
 
// Subscribe to the PubNub channel.
$.Deferred(
function( deferred ){
 
// When the PubNub connection has been
// established, resolve the deferred container.
PUBNUB.subscribe({
channel: "hello_world",
callback: receiveMessage,
connect: deferred.resolve,
error: deferred.fail
});
 
}
)
 
);
 
// When the UUID has come back, prepare the user for use
// within the system.
init.done(
function( uuid ){
 
// Store the UUID with the user.
user.uuid = uuid;
 
// Flag the user as subscribed.
user.subscribed = true;
 
// Enable the message form.
dom.formSubmit.removeAttr( "disabled" );
 
}
);
 
 
// -------------------------------------------------- //
// -------------------------------------------------- //
// -------------------------------------------------- //
// -------------------------------------------------- //
 
 
// NOTE: The following are just PubNub utility methods that
// have been converted from callback-based responses to
// deferred-based promises.
 
 
// I get a UUID from the PUBNUB server. I return a promise
// of the value to be returned.
function getUUID(){
 
// Since the core UUID method uses a callback, we need to
// create our own intermediary deferred object to wire
// the two workflows together.
var deferred = $.Deferred();
 
// Ask PubNub for a UUID.
PUBNUB.uuid(
function( uuid ){
 
// Resolve the uuid promise.
deferred.resolve( uuid );
 
}
);
 
// Return the UUID promise.
return( deferred.promise() );
 
}
 
</script>
 
</body>
</html>